package  control
{
	import com.greensock.easing.Cubic;
	import com.greensock.TweenLite;
	import events.MyEvent;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;

	/**
	 * ...
	 * 用法
	 * public function scroll(_x:Number,_y:Number):void
		{
			scrollContainer = new Sprite();
			scrollContainer.x = _x;
			scrollContainer.y = _y;
			this.addChild(scrollContainer);
			scrollContainer.addChild(container);
			scrollContainer.addChild(mask_mc);
			container.x = 0;
			container.y = 0;
			mask_mc.x = 0;
			mask_mc.y = 0;
			container.mask = mask_mc;
			scrollContainer.addChild(tracer);
			tracer.x = mask_mc.x + mask_mc.width +6+(scrollbg.width-tracer.width)/2;
			
			scrollContainer.addChild(scrollbg);
			scrollbg.x = mask_mc.x + mask_mc.width + 6;
			
			scrollContainer.addChild(dragger);
			dragger.x = scrollbg.x;
			scrollManager = new SimpleScroll( container, dragger, scrollbg);
		}
	 * @author FireKnight
	 */
	public class SimpleScroll 
	{
		private var container:Sprite;
		public var _mask_mc:Sprite;
		private var dragger:Sprite;
		private var scrollbg:Sprite;
		private var tracer:Sprite;
		private var dragRect:Rectangle;
		private var scrollHeight:Number;
		private var scrollable:Number;
		private var easingSpeed:Number = 10;
		private var moveSpeed:Number = 10;
		private var top:Number;
		private var bottom:Number;
		public var _hitArea:Sprite;
		public var distance:Number = 0;
		protected var startMouseY:Number = 0;
		protected var endMouseY:Number = 0;
		public var dif:Number = 0;//上下偏差
		public function SimpleScroll(_con:Sprite,_dragger:Sprite,_scrollbg:Sprite,_tarcer:Sprite,_hit:Sprite,_speed:Number=10,easing:Number=0) 
		{
			container = _con;
			tracer = _tarcer;
			dragger = _dragger;
			scrollbg = _scrollbg;
			_hitArea=_hit;
			_speed = moveSpeed;
			easingSpeed = easing;
			init();
		}
		
		private function init():void
		{
			scrollHeight=scrollbg.height;
			scrollable = container.height - scrollHeight;
			bottom = scrollbg.y + scrollbg.height - dragger.height;
			top = scrollbg.y;
			if (test())
			{
				if (dragRect)
				{
					dragRect = null;
				}
				//scrollable+=100;
				dragRect = new Rectangle(scrollbg.x, scrollbg.y, 0, bottom);
				scrollbg.addEventListener(MouseEvent.MOUSE_DOWN, onScrollBgMouseDown, false, 0, true);
				dragger.addEventListener(MouseEvent.MOUSE_DOWN, onDraggerMouseDown, false, 0, true);
			}
			
		}
		
		public function relive():void
		{
			if (test())
			{
				scrollbg.addEventListener(MouseEvent.MOUSE_DOWN, onScrollBgMouseDown, false, 0, true);
				dragger.addEventListener(MouseEvent.MOUSE_DOWN, onDraggerMouseDown, false, 0, true);
				addcontainerEvent();
			}
			
		}
		
		
		private function removeBtEvent():void
		{
			if (scrollbg.hasEventListener(MouseEvent.MOUSE_DOWN))
			{
				scrollbg.removeEventListener(MouseEvent.MOUSE_DOWN, onScrollBgMouseDown);
			}
			if (dragger.hasEventListener(MouseEvent.MOUSE_DOWN))
			{
				dragger.removeEventListener(MouseEvent.MOUSE_DOWN, onDraggerMouseDown);
			}
		}
		
		private function test():Boolean
		{
			var bo:Boolean = true;
			if (scrollable <= 0) {
				removeBtEvent();
				if(tracer)
				{
					tracer.visible = false;
				}
				
				dragger.visible = false;
				scrollbg.visible = false;
				bo = false;
				 removecontainerEvent();
			} else {
				bo = true;
				if(tracer)
				{
					tracer.visible = true;
				}
				
				dragger.visible = true;
				scrollbg.visible = true;
				addcontainerEvent();
				addHitAreaEvent();
			}
			return bo;
		}//end test
		
		private function addcontainerEvent():void
		{
			container.addEventListener(Event.ENTER_FRAME,containerOnEnterFrame, false, 0, true);
		}//end addcontainerEvent
		
		private function containerMainOnMouseWh(event:MouseEvent):void
		{
			
			dragger.y-=event.delta*moveSpeed;
			if (scrollThumbUpCanMove() )
			{
				
				dragger.y=scrollbg.y+scrollbg.height-dragger.height;
			}
			else if ( scrollThumbDownCanMove())
			{
				
				dragger.y=scrollbg.y;
			}
			
			updatecontainerPos();
		}//end containerMainOnMouseWh
		
		
		
		private function scrollThumbUpCanMove():Boolean
		{
			return !((dragger.y + dragger.height) < (scrollbg.y + scrollbg.height)) ;
		}//end scrollThumbCanMove
		
		private function scrollThumbDownCanMove():Boolean
		{
			return !(dragger.y > scrollbg.y);
		}//end scrollThumbCanMove
		
		private function removecontainerEvent():void
		{
			
			if (container.hasEventListener(Event.ENTER_FRAME))
			{
				container.removeEventListener(Event.ENTER_FRAME, containerOnEnterFrame);
			}
			
		}//end removecontainerEvent
		
		private function onScrollBgMouseDown(e:MouseEvent):void
		{
			var nowPosition:Number;
			if (scrollbg.mouseY < dragger.height / 2)
			{
				nowPosition=top;
			}
			else if (bottom - scrollbg.mouseY < dragger.height / 2) 
			{
				nowPosition=bottom;
			}
			else 
			{
				nowPosition=scrollbg.mouseY - dragger.height / 2;
			}
			dragger.y = nowPosition;
		}
		
		private function onDraggerMouseDown(e:MouseEvent):void
		{
			dragger.startDrag(false,dragRect);
			container.stage.addEventListener(MouseEvent.MOUSE_UP,draggerOnMouseUp, false, 0, true);
		}
		
		
		private function draggerOnMouseUp(event:MouseEvent):void
		{
			dragger.stopDrag();
			container.stage.removeEventListener(MouseEvent.MOUSE_UP,draggerOnMouseUp);
		}//end draggerOnMouseUp
		
		private function containerOnEnterFrame(event:Event):void 
		{
			if (easingSpeed>0)
			{
				var distance:Number=updatecontainerPos() - container.y;
				container.y+= distance / easingSpeed;

			}
			else
			{
				container.y=updatecontainerPos() ;
			}
		}//end containerOnEnterFrame
		
		private function updatecontainerPos():Number
		{
			var lastheight:Number = scrollHeight - dragger.height ;
			var percent_scrolled:Number = dragger.y / lastheight;
			var newY:Number=- scrollable * percent_scrolled;
			return newY;
		}//end updatecontainerPos
		
		public function updateDraggerPosition():void
		{
			var pecent_scrolled:Number = -Math.round(container.y) /  scrollable;
			var lastHeight:Number = scrollHeight - dragger.height;
			dragger.y = Math.round(lastHeight * pecent_scrolled);
			if (scrollThumbUpCanMove() )
			{
				
				dragger.y=scrollbg.y+scrollbg.height-dragger.height;
			}
			else if ( scrollThumbDownCanMove())
			{
				
				dragger.y=scrollbg.y;
			}
			
		}
		
		
		public function addHitAreaEvent():void
		{
			_hitArea.addEventListener(MouseEvent.MOUSE_DOWN, handleMaskMouseDown);
		}
		
		
		public function removeHitAreaEvent():void
		{
			if (_hitArea)
			{
				if (_hitArea.hasEventListener(MouseEvent.MOUSE_DOWN))
				{
					_hitArea.removeEventListener(MouseEvent.MOUSE_DOWN, handleMaskMouseDown);
				}
			}
		}
		
		protected function handleMouseUp(e:MouseEvent):void
		{
			addcontainerEvent();
			container.parent.stage.removeEventListener(MouseEvent.MOUSE_UP, handleMouseUp);
			container.parent.stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove);
		}
		
		protected function handleMaskMouseDown(e:MouseEvent):void
		{
			container.dispatchEvent(new MyEvent("moved",null,true));
			distance = 0;
			trace("handleMaskMouseDown");
			removecontainerEvent();
				startMouseY = container.parent.mouseY;
				container.parent.stage.addEventListener(MouseEvent.MOUSE_UP, handleMouseUp);
				container.parent.stage.addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove);
		}
		
		
		protected function handleMouseMove(e:MouseEvent):void
		{
			endMouseY = container.parent.mouseY;
			distance = startMouseY - endMouseY;
			moveFunction();
		}
		
		protected function moveFunction():void
		{
			var _target:Number = container.y - distance;
			if (_target > _mask_mc.y+dif)
				_target = _mask_mc.y+dif;
			if (_target < _mask_mc.y - container.height + _mask_mc.height-dif-100)
				_target = _mask_mc.y - container.height + _mask_mc.height-dif-100;
			TweenLite.to(container, 0.5, { y: _target, ease: Cubic.easeOut,onUpdate:updateDraggerPosition,onComplete:updateDraggerPosition} );
			
		}
		
		
		
		public function gc():void
		{
			removecontainerEvent();
			removeBtEvent();
			removeHitAreaEvent();
		}
		
	}

}